<template>
  <div class="space-y-6">
    <h2 class="text-xl font-semibold text-gray-800">OCR 识别</h2>

    <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
      <!-- 左侧：上传 -->
      <div class="space-y-4">
        <!-- 图片上传区 -->
        <div class="bg-white rounded-lg shadow p-6">
          <h3 class="text-lg font-medium mb-4">上传图片</h3>
          
          <div
            @drop.prevent="handleDrop"
            @dragover.prevent
            @dragenter.prevent
            class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-500 transition-colors cursor-pointer"
          >
            <input
              ref="fileInput"
              type="file"
              accept="image/*"
              @change="handleFileSelect"
              class="hidden"
            />
            
            <div v-if="!selectedImage" @click="$refs.fileInput.click()">
              <p class="text-gray-500 mb-2">点击或拖拽图片到这里</p>
              <p class="text-sm text-gray-400">支持 JPG、PNG 等格式</p>
            </div>
            
            <div v-else class="space-y-4">
              <img :src="selectedImagePreview" alt="预览" class="max-w-full max-h-64 mx-auto rounded" />
              <p class="text-sm text-gray-600">{{ selectedFileName }}</p>
              <button
                @click="clearImage"
                class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200"
              >
                重新选择
              </button>
            </div>
          </div>
          
          <button
            v-if="selectedImage"
            @click="recognize"
            :disabled="recognizing || !selectedModel"
            class="mt-4 w-full px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:bg-gray-400 disabled:cursor-not-allowed"
          >
            {{ recognizing ? '识别中...' : selectedModel ? '开始识别' : '请先在设置页面配置模型' }}
          </button>
          
          <div v-if="!selectedModel" class="mt-2 text-sm text-amber-600 bg-amber-50 border border-amber-200 rounded-lg p-3">
            <p>⚠️ 请先在"设置"页面配置 OCR 模型</p>
          </div>
        </div>
      </div>

      <!-- 右侧：识别结果和字段映射 -->
      <div class="space-y-4">
        <!-- 识别结果 -->
        <div class="bg-white rounded-lg shadow p-6">
          <h3 class="text-lg font-medium mb-4">识别结果</h3>
          
          <div v-if="recognizing" class="text-center py-8">
            <p class="text-gray-500">正在识别中...</p>
            <div v-if="streamingText" class="mt-4 max-h-96 overflow-y-auto border border-gray-200 rounded-lg p-4 bg-gray-50">
              <p class="text-gray-700 whitespace-pre-wrap">{{ streamingText }}</p>
              <span class="inline-block w-2 h-4 bg-blue-500 animate-pulse ml-1">|</span>
            </div>
          </div>
          
          <div v-else-if="ocrResult" class="space-y-4">
            <div v-if="ocrResult.data" class="max-h-96 overflow-y-auto space-y-3 border border-gray-200 rounded-lg p-4">
              <div
                v-for="(value, key) in ocrResult.data"
                :key="key"
                class="flex items-center justify-between p-3 bg-gray-50 rounded-lg"
              >
                <span class="font-medium text-gray-700">{{ key }}</span>
                <span class="text-gray-900">{{ value }}</span>
              </div>
            </div>
            
            <div v-else-if="ocrResult.text" class="max-h-96 overflow-y-auto border border-gray-200 rounded-lg p-4 bg-gray-50">
              <p class="text-gray-700 whitespace-pre-wrap">{{ ocrResult.text }}</p>
            </div>
            
            <div v-if="ocrResult.error" class="text-red-500 p-3 bg-red-50 border border-red-200 rounded-lg">
              {{ ocrResult.error }}
            </div>
            
            <button
              v-if="ocrResult.data || ocrResult.text"
              @click="showMappingConfig = true"
              class="w-full px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600"
            >
              设置字段映射
            </button>
          </div>
          
          <div v-else class="text-center py-8 text-gray-400">
            <p>识别结果将显示在这里</p>
          </div>
        </div>

        <!-- 字段映射配置 -->
        <div v-if="showMappingConfig" class="bg-white rounded-lg shadow p-6">
          <h3 class="text-lg font-medium mb-4">字段映射配置</h3>
          
          <div class="space-y-3">
            <div>
              <label class="block text-sm font-medium text-gray-700 mb-1">选择模板</label>
              <select
                v-model="selectedTemplateForMapping"
                @change="loadTemplateMapping"
                class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
              >
                <option value="">请选择模板</option>
                <option v-for="template in templates" :key="template.id" :value="template.id">
                  {{ template.name }}
                </option>
              </select>
            </div>
            
            <div v-if="selectedTemplateForMapping && ocrFields.length > 0" class="space-y-2">
              <div
                v-for="ocrField in ocrFields"
                :key="ocrField"
                class="flex items-center gap-2"
              >
                <span class="flex-1 text-sm text-gray-700">{{ ocrField }}</span>
                <span class="text-sm text-gray-400">→</span>
                <select
                  v-model="mappingRules[ocrField]"
                  class="flex-1 px-2 py-1 border border-gray-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                >
                  <option value="">不映射</option>
                  <option v-for="varName in templateVariables" :key="varName" :value="varName">
                    {{ varName }}
                  </option>
                </select>
              </div>
              
              <button
                @click="saveMapping"
                class="mt-4 w-full px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
              >
                保存映射规则
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { ocrAPI, fieldMappingAPI, templateAPI, configAPI } from '../api/app.js'

const fileInput = ref(null)
const selectedImage = ref(null)
const selectedImagePreview = ref(null)
const selectedFileName = ref('')
const imageBase64 = ref('')
const recognizing = ref(false)
const ocrResult = ref(null)
const streamingText = ref('')

const models = ref([])
const selectedModel = ref('')
const showMappingConfig = ref(false)
const selectedTemplateForMapping = ref('')
const templates = ref([])
const templateVariables = ref([])
const mappingRules = ref({})

const ocrFields = computed(() => {
  if (!ocrResult.value) return []
  if (ocrResult.value.data) {
    return Object.keys(ocrResult.value.data)
  }
  return []
})

const loadModelFromConfig = async () => {
  try {
    // 从配置中加载已保存的模型
    const config = await configAPI.get()
    if (config.ocrModelID) {
      selectedModel.value = config.ocrModelID
    }
  } catch (error) {
    console.error('加载模型配置失败:', error)
  }
}

const handleFileSelect = (event) => {
  const file = event.target.files[0]
  if (file) {
    processFile(file)
  }
}

const handleDrop = (event) => {
  const file = event.dataTransfer.files[0]
  if (file && file.type.startsWith('image/')) {
    processFile(file)
  }
}

const processFile = (file) => {
  selectedFileName.value = file.name
  const reader = new FileReader()
  reader.onload = (e) => {
    selectedImagePreview.value = e.target.result
    const fullBase64 = e.target.result
    imageBase64.value = fullBase64.includes(',') ? fullBase64.split(',')[1] : fullBase64
    selectedImage.value = file
  }
  reader.readAsDataURL(file)
}

const clearImage = () => {
  selectedImage.value = null
  selectedImagePreview.value = null
  selectedFileName.value = ''
  imageBase64.value = ''
  ocrResult.value = null
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}

const recognize = async () => {
  if (!selectedModel.value) {
    alert('请先在设置页面配置 OCR 模型')
    return
  }
  
  if (!imageBase64.value) {
    alert('请先选择图片')
    return
  }
  
  recognizing.value = true
  ocrResult.value = null
  streamingText.value = ''
  
  try {
    let fullText = ''
    await ocrAPI.recognizeWithSiliconFlowStream(selectedModel.value, imageBase64.value, (chunk) => {
      fullText += chunk
      streamingText.value = fullText
    })
    
    const result = { text: streamingText.value }
    try {
      result.data = JSON.parse(streamingText.value)
      showMappingConfig.value = true
    } catch (e) {}
    
    ocrResult.value = result
    streamingText.value = ''
  } catch (error) {
    ocrResult.value = { error: error.message || '识别失败' }
  } finally {
    recognizing.value = false
  }
}

const loadTemplates = async () => {
  try {
    templates.value = await templateAPI.list()
  } catch (error) {
    console.error('加载模板失败:', error)
  }
}

const loadTemplateMapping = async () => {
  if (!selectedTemplateForMapping.value) {
    templateVariables.value = []
    return
  }
  
  try {
    const template = templates.value.find(t => t.id === selectedTemplateForMapping.value)
    if (template) {
      templateVariables.value = template.variables || []
    }
    
    // 加载已有的映射规则
    const mapping = await fieldMappingAPI.get(selectedTemplateForMapping.value)
    if (mapping && mapping.rules) {
      mappingRules.value = {}
      mapping.rules.forEach(rule => {
        mappingRules.value[rule.ocrField] = rule.templateVar
      })
    }
  } catch (error) {
    console.error('加载映射规则失败:', error)
  }
}

const saveMapping = async () => {
  if (!selectedTemplateForMapping.value) {
    alert('请先选择模板')
    return
  }
  
  try {
    const rules = Object.keys(mappingRules.value)
      .filter(key => mappingRules.value[key])
      .map(key => ({
        ocrField: key,
        templateVar: mappingRules.value[key],
      }))
    
    const mapping = {
      templateId: selectedTemplateForMapping.value,
      rules: rules,
    }
    
    await fieldMappingAPI.save(mapping)
    alert('映射规则已保存')
  } catch (error) {
    console.error('保存映射规则失败:', error)
    alert('保存失败: ' + error.message)
  }
}

onMounted(async () => {
  loadTemplates()
  await loadModelFromConfig()
})
</script>
